/* eslint-disable @typescript-eslint/no-explicit-any */
import React, { useMemo, useRef, useState, useCallback } from 'react';
import { HotTable } from '@handsontable/react';
import 'handsontable/dist/handsontable.full.min.css';


interface SheetEditorProps {
  value: string | undefined;
  onChange: (content: string) => void;
}

// 可视化表格编辑器组件
const SheetEditor: React.FC<SheetEditorProps> = ({ value, onChange }) => {
  const [fallbackText, setFallbackText] = useState<string>(() => value || JSON.stringify([['任务', '负责人', '进度(%)'], ['需求梳理', '张三', 100], ['设计联调', '李四', 60], ['功能开发', '王五', 30]], null, 2));
  const [hotReady] = useState(true); // 直接使用本地安装的Handsontable
  const hotRef = useRef<any>(null);
  const containerRef = useRef<HTMLDivElement | null>(null);
  const dataInitialized = useRef(false);
  
  // 解析表格数据
  const dataArray = useMemo(() => {
    try {
      const parsed = value ? JSON.parse(value) : [['任务', '负责人', '进度(%)'], ['需求梳理', '张三', 100], ['设计联调', '李四', 60], ['功能开发', '王五', 30]];
      return Array.isArray(parsed) ? parsed : [['任务', '负责人', '进度(%)']];
    } catch {
      return [['任务', '负责人', '进度(%)']];
    }
  }, [value]);

  // 优化onChange回调，避免无限循环
  const handleDataChange = useCallback((_changes: any, source: string) => {
    // 防止初始化时触发change事件导致的循环更新
    if (source === 'loadData' || !dataInitialized.current) {
      if (source === 'loadData') {
        dataInitialized.current = true;
      }
      return;
    }
    
    try {
      // 只从hotInstance获取数据，避免依赖dataArray
      const hotInstance = hotRef.current?.hotInstance;
      if (hotInstance) {
        const tableData = hotInstance.getData();
        const newDataString = JSON.stringify(tableData);
        
        // 只有当数据真正变化时才调用onChange，避免循环更新
        if (newDataString !== value) {
          onChange(newDataString);
        }
      }
    } catch (error) {
      console.error('更新数据失败:', error);
    }
  }, [onChange, value]);

  // 表格配置项
  const tableSettings = useMemo(() => ({
    data: dataArray,
    rowHeaders: true,
    colHeaders: true,
    licenseKey: 'non-commercial-and-evaluation',
    stretchH: 'all' as const,
    // 让列宽由 AutoColumnSize 计算，去掉固定列宽
    width: '100%' as unknown as number,
    height: 400,
    manualColumnResize: true,
    manualColumnMove: true,
    autoColumnSize: true,
    // 关掉以下未实现或未注册插件相关功能，避免报错
    mergeCells: false,
    filters: false,
    dropdownMenu: false,
    contextMenu: true,
    afterInit: function (this: any) {
      (window as any).__sheetInst__ = this;
      dataInitialized.current = true;
    },
    afterChange: handleDataChange
  }), [dataArray, handleDataChange]);

  return (
    <div className="space-y-4">
      {!hotReady ? (
        <>
          <div className="text-sm text-gray-500">表格编辑器未就绪，已降级为 JSON 编辑</div>
          <textarea
            className="w-full h-72 p-3 border rounded font-mono text-sm"
            value={fallbackText}
            onChange={(e) => {
              setFallbackText(e.target.value);
              onChange(e.target.value);
            }}
          />
        </>
      ) : (
        <div>
          <div className="mb-4">
            <div className="font-medium text-lg mb-2">可视化表格（Handsontable）</div>
            {/* 工具栏分组显示 */}
            <SheetToolbar />
          </div>
          <div ref={containerRef} className="border rounded-md">
            {/* 使用React版本的Handsontable */}
            <HotTable
              ref={hotRef}
              {...tableSettings}
            />
          </div>
        </div>
      )}
    </div>
  );
};

export default SheetEditor;

// 顶部工具栏组件
const SheetToolbar: React.FC = () => {
  // ========== 导出功能 ==========
  const exportXlsx = async () => {
    try {
      // 动态导入xlsx库
      const XLSX = await import('xlsx');
      const inst = (window as any).__sheetInst__;
      if (!inst || !XLSX) return;
      
      const data: any[][] = inst.getData();
      const ws = XLSX.utils.aoa_to_sheet(data);
      const wb = XLSX.utils.book_new();
      XLSX.utils.book_append_sheet(wb, ws, 'Sheet1');
      
      // 生成文件名
      const ts = new Date();
      const yyyy = ts.getFullYear();
      const mm = String(ts.getMonth() + 1).padStart(2, '0');
      const dd = String(ts.getDate()).padStart(2, '0');
      
      XLSX.writeFile(wb, `sheet-${yyyy}${mm}${dd}.xlsx`);
    } catch (error) {
      console.error('导出XLSX失败:', error);
    }
  };

  const exportCsv = () => {
    try {
      const inst = (window as any).__sheetInst__;
      if (!inst) return;
      
      const exporter = inst.getPlugin && inst.getPlugin('exportFile');
      if (exporter?.downloadFile) {
        const ts = new Date();
        const yyyy = ts.getFullYear();
        const mm = String(ts.getMonth() + 1).padStart(2, '0');
        const dd = String(ts.getDate()).padStart(2, '0');
        
        exporter.downloadFile('csv', {
          bom: true,
          columnDelimiter: ',',
          columnHeaders: true,
          rowHeaders: true,
          exportHiddenColumns: false,
          exportHiddenRows: false,
          fileExtension: 'csv',
          filename: `sheet-${yyyy}${mm}${dd}`,
          mimeType: 'text/csv',
        });
      }
    } catch (error) {
      console.error('导出CSV失败:', error);
    }
  };

  // ========== 导入功能 ==========
  const importFile = async () => {
    const input = document.createElement('input');
    input.type = 'file';
    input.accept = '.csv,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel';
    input.onchange = async () => {
      const file = input.files?.[0];
      if (!file) return;
      
      const inst = (window as any).__sheetInst__;
      if (!inst) return;
      
      const ext = file.name.split('.').pop()?.toLowerCase();
      
      if (ext === 'csv') {
        const text = await file.text();
        const rows = text.split(/\r?\n/).map(l => l.split(','));
        inst.loadData(rows);
        return;
      }
      
      // xlsx格式
      try {
        const XLSX = await import('xlsx');
        const buf = await file.arrayBuffer();
        const wb = XLSX.read(buf, { type: 'array' });
        const first = wb.SheetNames[0];
        const ws = wb.Sheets[first];
        const aoa = XLSX.utils.sheet_to_json(ws, { header: 1 });
        inst.loadData(aoa);
      } catch (error) {
        console.error('导入XLSX失败:', error);
      }
    };
    input.click();
  };

  const autosize = () => {
    try {
      const inst = (window as any).__sheetInst__;
      if (!inst) return;
      
      // 启用并强制重新计算所有列宽
      inst.updateSettings({ autoColumnSize: true, manualColumnResize: false, colWidths: undefined });
      const plugin = inst.getPlugin && inst.getPlugin('autoColumnSize');
      // 尝试清理缓存并重新计算
      if (plugin?.clearCache) {
        plugin.clearCache();
      }
      if (plugin?.recalculateAllColumnsWidth) {
        plugin.recalculateAllColumnsWidth();
      }
      // 作为兜底，触发一次数据重载以强制应用自动列宽
      const data = inst.getData();
      inst.loadData(data);
      inst.render();
    } catch (error) {
      console.error('自适应列宽失败:', error);
    }
  };

  // ========== 插入行列功能 ==========
  const insertRows = () => {
    try {
      const inst = (window as any).__sheetInst__;
      if (!inst) return;
      
      const countStr = window.prompt('插入行数（默认1）') || '1';
      const count = Math.max(1, Number(countStr) || 1);
      
      const sel = inst.getSelectedLast?.();
      const totalRows = typeof inst.countRows === 'function' ? inst.countRows() : (inst.getData()?.length || 0);
      
      if (sel && Number.isFinite(sel[0])) {
        const row = Math.max(0, sel[0]);
        // 在当前选中行上方插入
        inst.alter('insert_row_above', row, count);
      } else {
        // 未选中时，在末尾插入
        const row = Math.max(0, totalRows);
        inst.alter('insert_row_below', row - 1, count);
      }
    } catch (error) {
      console.error('插入行失败:', error);
    }
  };

  const insertCols = () => {
    try {
      const inst = (window as any).__sheetInst__;
      if (!inst) return;
      
      const countStr = window.prompt('插入列数（默认1）') || '1';
      const count = Math.max(1, Number(countStr) || 1);
      
      const sel = inst.getSelectedLast?.();
      const totalCols = typeof inst.countCols === 'function'
        ? inst.countCols()
        : Math.max(0, ...(inst.getData() || []).map((r: any[]) => r?.length || 0));
      
      if (sel && Number.isFinite(sel[1])) {
        const col = Math.max(0, sel[1]);
        // 在当前选中列前方插入
        inst.alter('insert_col_start', col, count);
      } else {
        // 未选中时，在末尾插入
        const col = Math.max(0, totalCols);
        inst.alter('insert_col_end', col, count);
      }
    } catch (error) {
      console.error('插入列失败:', error);
    }
  };

  // 分组显示工具栏按钮
  return (
    <div className="flex flex-wrap items-center gap-2 pb-2 border-b">
      {/* 导出导入组 */}
      <div className="flex items-center gap-1 mr-4">
        <button onClick={exportCsv} className="px-3 py-1 text-sm rounded border border-gray-300 hover:bg-gray-50">导出CSV</button>
        <button onClick={exportXlsx} className="px-3 py-1 text-sm rounded border border-gray-300 hover:bg-gray-50">导出XLSX</button>
        <button onClick={importFile} className="px-3 py-1 text-sm rounded border border-gray-300 hover:bg-gray-50">导入CSV/XLSX</button>
      </div>
      
      {/* 视图控制组 */}
      <div className="flex items-center gap-1 mr-4">
        <button onClick={autosize} className="px-3 py-1 text-sm rounded border border-gray-300 hover:bg-gray-50">自适应列宽</button>
      </div>
      
      {/* 结构操作组 */}
      <div className="flex items-center gap-1">
        <button onClick={insertRows} className="px-3 py-1 text-sm rounded border border-gray-300 hover:bg-gray-50">插入行</button>
        <button onClick={insertCols} className="px-3 py-1 text-sm rounded border border-gray-300 hover:bg-gray-50">插入列</button>
      </div>
    </div>
  );
};

